package config

import (
	"go-micro.dev/v4"
)

var (
	Conf         *Config
	MicroService micro.Service
	EtcdAddr     = ""
	configFile   = ""
	ExitC        = make(chan bool)
	prefix       = "/ebike/config/ota"
)

type Config struct {
	Name        string `json:"name" yaml:"name" toml:"name"`
	Env         string `json:"env" yaml:"env" toml:"env"`
	Version     string `json:"version" yaml:"version" toml:"version"`
	AutoMigrate bool   `json:"auto_migrate" yaml:"auto_migrate" toml:"auto_migrate"`
	HttpListen  string `json:"http_listen" yaml:"http_listen" toml:"http_listen"`

	Grpc struct {
		GrpcListen      string `json:"grpc_listen" yaml:"grpc_listen" toml:"grpc_listen"`
		DiscoveryListen string `json:"discovery_listen" yaml:"discovery_listen" toml:"discovery_listen"`
		ValidateTrans   string `json:"validate_trans" yaml:"validateTrans" toml:"validate_trans"`
	}

	Collect Collect `json:"collect" yaml:"collect" toml:"collect"`

	DB []struct {
		Addr    string `json:"addr" yaml:"addr" toml:"addr"` // host=127.0.0.1 user=root password=root dbname=signal port=5432 sslmode=disable TimeZone=Asia/Shanghai
		Name    string `json:"name" yaml:"name" toml:"name"`
		Type    string `json:"type" yaml:"type" toml:"type"` // postgres, mysql, sqlite, mongo
		User    string `json:"user" yaml:"user" toml:"user"` // if addr not like Addr example or other need, you should set
		Pwd     string `json:"pwd" yaml:"pwd" toml:"pwd"`
		Enabled bool   `json:"enabled" yaml:"enabled" toml:"enabled"`
	} `json:"db" yaml:"db" toml:"db"`

	Broker struct {
		Type    string `json:"type" yaml:"type" toml:"type"` // support: rabbitmq, nats
		Addr    string `json:"addr" yaml:"addr" toml:"addr"`
		User    string `json:"user" yaml:"user" toml:"user"`
		Pwd     string `json:"pwd" yaml:"pwd" toml:"pwd"`
		Enabled bool   `json:"enabled" yaml:"enabled" toml:"enabled"`
	} `json:"broker" yaml:"broker" toml:"broker"`

	Traefik struct {
		Type    string `json:"type" yaml:"type" toml:"type"`          // support tcp,http,grpc,udp
		Rule    string `json:"rule" yaml:"rule" yaml:"toml"`          // router rule  value: "||", "&&"
		TLS     bool   `json:"tls" yaml:"tls" yaml:"tls"`             // is or not enable tls
		Enabled bool   `json:"enabled" yaml:"enabled" toml:"enabled"` // is or not register traefik
		Domain  string `json:"domain" yaml:"domain" toml:"domain"`    // gateway domain
		Prefix  string `json:"prefix" yaml:"prefix" toml:"prefix"`    // if Prefix is not empty, it will register router and middleware
	} `json:"traefik" yaml:"traefik" toml:"traefik"`

	OSS                  OSSSettings          `json:"oss_settings" yaml:"oss_settings" toml:"oss_settings"`
	OTA                  OTASettings          `json:"ota_settings" yaml:"ota_settings" toml:"ota_settings"`
	FirmwareTypeSettings FirmwareTypeSettings `json:"firmware_type_settings" yaml:"firmware_type_settings" toml:"firmware_type_settings"`
	Simulator            Simulator
}

type Simulator struct {
	Enable bool `json:"enable" yaml:"enable" toml:"enable"`
}

type OSSSettings struct {
	StsEndPoint  string `json:"sts_endpoint" yaml:"sts_endpoint" toml:"sts_endpoint"`
	EndPoint     string `json:"endpoint" yaml:"endpoint" toml:"endpoint"`
	AccessKey    string `json:"access_key" yaml:"access_key" toml:"access_key"`
	AccessSecret string `json:"access_secret" yaml:"access_secret" toml:"access_secret"`
	Bucket       string `json:"bucket" yaml:"bucket" toml:"bucket"`
	Region       string `json:"region" yaml:"region" toml:"region"`
	Role         string `json:"role" yaml:"role" toml:"role"`
}

type OTASettings struct {
	Timeout int `json:"timeout" yaml:"timeout" toml:"timeout"`
}

type FirmwareTypeSettings struct {
	List []FirmwareTypeSettingsItem `json:"list" yaml:"list" toml:"list"`
}

func (a *FirmwareTypeSettings) ToMap() map[uint16]interface{} {

	var (
		m = make(map[uint16]interface{})
	)

	for _, item := range a.List {
		m[item.DeviceProtocolCmd] = item.DisplayName
	}
	return m
}

func (a *FirmwareTypeSettings) ToMap1() map[string]FirmwareTypeSettingsItem {

	var (
		m = make(map[string]FirmwareTypeSettingsItem)
	)

	for _, item := range a.List {
		m[item.DisplayName] = item
	}
	return m
}

type FirmwareTypeSettingsItem struct {
	DisplayName        string `json:"display_name" yaml:"display_name" toml:"display_name"`
	DisplayDescription string `json:"display_description" yaml:"display_description" toml:"display_description"`
	DeviceProtocolCmd  uint16 `json:"device_protocol_cmd" yaml:"device_protocol_cmd" toml:"device_protocol_cmd"`
}

type Collect struct {
	Log struct {
		LogLevel   int8   `json:"log_level" yaml:"log_level" toml:"log_level"` // log level support -1:5
		Prefix     string `json:"prefix" yaml:"prefix" toml:"prefix"`
		FileName   string `json:"file_name"  yaml:"file_name" toml:"file_name"`
		BufferSize int    `json:"buffer_size" yaml:"buffer_size" toml:"buffer_size"`
		Interval   int64  `json:"interval" yaml:"interval" toml:"interval"`
	} `json:"log" yaml:"log" toml:"log"`

	Trace struct {
		Enabled  bool   `json:"enabled" yaml:"enabled" toml:"enabled"`
		Protocol string `json:"protocol" yaml:"protocol" toml:"protocol"` // trace report way "http" or "grpc"
		Type     string `json:"type" yaml:"type" toml:"type"`             // trace report type "otel" or "jaeger" or "zipkin"
		Addr     string `json:"addr" yaml:"addr" toml:"addr"`
	} `json:"trace" yaml:"trace" toml:"trace"`

	Metric struct {
		Enabled bool   `json:"enabled" yaml:"enabled" toml:"enabled"`
		Listen  string `json:"listen" yaml:"listen" toml:"listen"` // prometheus fatch addr
	} `json:"metric" yaml:"metric" toml:"metric"`
}
